<template>
  <el-select 
    v-model="selectedAreaIds" 
    :placeholder="placeholder" 
    :style="{ width: width }"
    filterable
    remote
    :clearable="clearable"
    :multiple="multiple"
    :collapse-tags="collapseTags"
    :collapse-tags-tooltip="collapseTagsTooltip"
    :remote-method="handleAreaSearch"
    :loading="areaSearchLoading"
    @change="handleAreaChange">
    <el-option 
      v-for="item in areaOptions" 
      :key="item.value" 
      :label="item.label" 
      :value="item.value">
    </el-option>
  </el-select>
</template>

<script setup>
import { ref, watch, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { getWarehouseAreaList } from '@/api/modules/warehouseArea'
import { debounce } from 'lodash'

// 定义组件属性
const props = defineProps({
  modelValue: {
    type: [Array, String],
    default: () => []
  },
  placeholder: {
    type: String,
    default: '请选择目标库区'
  },
  width: {
    type: String,
    default: '100%'
  },
  // 是否可清空
  clearable: {
    type: Boolean,
    default: true
  },
  multiple: {
    type: Boolean,
    default: true
  },
  collapseTags: {
    type: Boolean,
    default: true
  },
  collapseTagsTooltip: {
    type: Boolean,
    default: true
  },
  // 只查询启用状态的库区
  enableFlag: {
    type: Number,
    default: 1
  },
  // 自定义使用哪个字段作为value值
  valueKey: {
    type: String,
    default: 'zoneId'
  },
  // 自定义label字段
  labelKey: {
    type: String,
    default: 'zoneName'
  }
})

// 定义组件事件
const emit = defineEmits(['update:modelValue', 'change'])

// 内部状态
const areaOptions = ref([])
const areaSearchLoading = ref(false)
const selectedAreaIds = ref(Array.isArray(props.modelValue) ? [...props.modelValue] : 
  props.modelValue ? props.multiple ? [props.modelValue] : props.modelValue : props.multiple ? [] : '')

// 监听外部值变化
watch(() => props.modelValue, (newVal) => {
  // 处理差异化的单选和多选模式
  if (props.multiple) {
    // 多选模式：确保值是数组
    const newValArray = Array.isArray(newVal) ? newVal : newVal ? [newVal] : []
    if (JSON.stringify(newValArray) !== JSON.stringify(selectedAreaIds.value)) {
      selectedAreaIds.value = newValArray
    }
  } else {
    // 单选模式：直接赋值，不需要数组包装
    if (newVal !== selectedAreaIds.value) {
      selectedAreaIds.value = newVal
    }
  }
})

// 监听内部值变化，同步到外部
watch(() => selectedAreaIds.value, (newVal) => {
  // 多选模式直接发送数组，单选模式发送值本身
  const valueToEmit = props.multiple ? newVal : newVal
  emit('update:modelValue', valueToEmit)
}, { deep: true })

// 获取库区列表
const fetchAreaList = async (keyword = '') => {
  try {
    // 构建查询参数
    const params = {
      zoneName: keyword,
      enableFlag: props.enableFlag // 根据属性决定是否只查询启用状态的库区
    }
    const res = await getWarehouseAreaList(params)
    if (res && (res.code === '200' || res.code === 200)) {
      // 处理库区列表数据
      const areaList = res.data || []
      areaOptions.value = areaList.map(item => ({
        label: item[props.labelKey] || item.zoneName,
        value: item[props.valueKey] || item.zoneId, // 使用自定义字段或默认zoneId作为value值
        rawData: item // 保存原始数据
      }))
    }
  } catch (error) {
    console.error('获取库区列表失败', error)
    ElMessage.error('获取库区列表失败')
  }
}

// 处理库区搜索，使用防抖函数减少请求次数
const handleAreaSearch = debounce((query) => {
  if (query) {
    areaSearchLoading.value = true
    fetchAreaList(query).finally(() => {
      areaSearchLoading.value = false
    })
  } else {
    fetchAreaList()
  }
}, 300)

// 处理库区变化事件
const handleAreaChange = (val) => {
  // 获取选中的库区详细数据
  let selectedData = null;
  
  if (props.multiple) {
    // 多选模式：返回选中项的完整数据数组
    selectedData = val.map(id => {
      const option = areaOptions.value.find(item => item.value === id);
      return option ? {
        id: option.value,
        label: option.label,
        // 返回原始数据
        rawData: option.rawData || option
      } : { id };
    });
  } else {
    // 单选模式：返回单个选中项的完整数据
    const option = areaOptions.value.find(item => item.value === val);
    selectedData = option ? {
      id: option.value,
      label: option.label,
      // 返回原始数据
      rawData: option.rawData || option
    } : null;
  }
  
  // 触发change事件，同时传递选中值和详细数据
  emit('change', val, selectedData);
}

// 获取库区详细信息（用于回显）
const fetchAreaDetails = async (areaIds) => {
  if (!areaIds || (Array.isArray(areaIds) && areaIds.length === 0)) return
  
  try {
    areaSearchLoading.value = true
    // 构建查询参数
    const params = {
      enableFlag: props.enableFlag
    }
    
    // 构造查询条件
    if (props.valueKey === 'zoneId') {
      params.zoneIds = Array.isArray(areaIds) ? areaIds.join(',') : areaIds
    } else {
      // 根据实际API支持的方式调整
      params[`${props.valueKey}s`] = Array.isArray(areaIds) ? areaIds.join(',') : areaIds
    }
    
    const res = await getWarehouseAreaList(params)
    
    if (res && (res.code === '200' || res.code === 200) && res.data) {
      // 将获取到的库区数据转换为选项格式并添加到选项列表中
      const areaData = res.data.map(item => ({
        value: item[props.valueKey] || item.zoneId,
        label: item[props.labelKey] || item.zoneName,
        rawData: item // 保存原始数据
      }))
      
      // 确保不重复添加
      areaData.forEach(item => {
        if (!areaOptions.value.some(option => option.value === item.value)) {
          areaOptions.value.push(item)
        }
      })
    }
  } catch (error) {
    console.error('获取库区详情失败', error)
  } finally {
    areaSearchLoading.value = false
  }
}

// 暴露方法给父组件使用
defineExpose({
  fetchAreaList,
  fetchAreaDetails
})

// 组件挂载时加载数据
onMounted(() => {
  // 初始加载库区列表
  fetchAreaList()
  
  // 如果已有选中的库区ID，加载对应的详情
  if (selectedAreaIds.value && (
      (Array.isArray(selectedAreaIds.value) && selectedAreaIds.value.length > 0) || 
      (!Array.isArray(selectedAreaIds.value) && selectedAreaIds.value)
    )) {
    fetchAreaDetails(selectedAreaIds.value)
  }
})
</script>

<style lang="scss" scoped>
/* 可能的特定样式 */
</style> 